home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
101-125
/
118
/
empire
/
src
/
source.zoo
/
serial.d
< prev
next >
Wrap
Text File
|
1987-12-02
|
8KB
|
366 lines
#include:exec/io.g
#include:exec/ports.g
#include:devices/serial.g
#include:hardware/cia.g
#include:libraries/dos.g
uint LINE_BUFFER_LENGTH = 100;
[LINE_BUFFER_LENGTH] char LineBuffer;
uint
LineBuffPos,
LineBuffMax,
LineSpeed;
bool EchoOn, SerialDropped;
*MsgPort_t MySerPort;
*IOExtSer_t MySerReq;
IOExtSer_t SaveParams;
/*
* setDTRoff - force DTR off.
*/
proc setDTRoff()void:
CIAB.cia_ciapra := CIAB.cia_ciapra | CIAF_COMDTR;
corp;
/*
* setDTRon - force DTR on.
*/
proc setDTRon()void:
CIAB.cia_ciapra := CIAB.cia_ciapra & ~CIAF_COMDTR;
corp;
/*
* checkDoIO - do and check a DoIO call for the serial device.
*/
proc checkDoIO(uint command; *char message)void:
uint errnum;
MySerReq*.ios_IOSer.io_io.io_Command := command;
errnum := DoIO(&MySerReq*.ios_IOSer.io_io);
if errnum ~= 0 then
writeln(message, " error on serial port: ", errnum);
fi;
corp;
/*
* setParams - issue an SCMD_SETPARAMS to serial device.
*/
proc setParams(bool parity)void:
checkDoIO(CMD_CLEAR, "setParams first clear");
MySerReq*.ios_CtlChar := 0x11130000;
MySerReq*.ios_Baud := LineSpeed;
MySerReq*.ios_TermArray.TermArray0 := 0xff7f1c04;
MySerReq*.ios_TermArray.TermArray1 := 0x03000000;
MySerReq*.ios_StopBits := 1;
if parity then
MySerReq*.ios_SerFlags := SERF_EOFMODE | SERF_PARTY_ON;
MySerReq*.ios_ReadLen := 7;
MySerReq*.ios_WriteLen := 7;
else
MySerReq*.ios_SerFlags := SERF_EOFMODE;
MySerReq*.ios_ReadLen := 8;
MySerReq*.ios_WriteLen := 8;
fi;
checkDoIO(SDCMD_SETPARAMS, "setParms");
checkDoIO(CMD_CLEAR, "setParams second clear");
corp;
/*
* openSerialHandler - initial open of serial device. Return 'true' if worked.
*/
proc openSerialHandler()bool:
MySerPort := CreatePort("MySerial", 0);
if MySerPort ~= nil then
MySerReq :=
pretend(CreateExtIO(MySerPort, sizeof(IOExtSer_t)), *IOExtSer_t);
if MySerReq ~= nil then
MySerReq*.ios_IOSer.io_io.io_Flags := SERF_7WIRE;
if OpenDevice("serial.device", 0,
&MySerReq*.ios_IOSer.io_io, 0) = 0 then
SaveParams := MySerReq*;
LineSpeed := 2400;
setParams(false);
LineBuffPos := 0;
LineBuffMax := 0;
EchoOn := true;
SerialDropped := false;
true
else
DeleteExtIO(&MySerReq*.ios_IOSer.io_io, sizeof(IOExtSer_t));
DeletePort(MySerPort);
false
fi
else
DeletePort(MySerPort);
false
fi
else
false
fi
corp;
/*
* closeSerialHandler - final close of serial device.
*/
proc closeSerialHandler()void:
SaveParams.ios_IOSer := MySerReq*.ios_IOSer;
MySerReq* := SaveParams;
checkDoIO(SDCMD_SETPARAMS, "close reset params");
CloseDevice(&MySerReq*.ios_IOSer.io_io);
DeleteExtIO(&MySerReq*.ios_IOSer.io_io, sizeof(IOExtSer_t));
DeletePort(MySerPort);
setDTRoff();
corp;
/*
* readSerial - low-level routine to read a single raw character.
*/
proc readSerial()char:
char ch;
if SerialDropped then
'\r'
else
checkDoIO(SDCMD_QUERY, "Read check");
/* if connection is dropped, return CR */
if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
SerialDropped := true;
'\r'
elif MySerReq*.ios_Status & (IOSTF_READBREAK << 8) ~= 0 then
'\r'
elif MySerReq*.ios_Status & (IOSTF_OVERRUN << 8) ~= 0 then
' '
else
MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
MySerReq*.ios_IOSer.io_Length := 1;
checkDoIO(CMD_READ, "Read");
ch
fi
fi
corp;
/*
* writeSerial - low-level routine to write a single raw character.
*/
proc writeSerial(char ch)void:
if not SerialDropped then
MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
MySerReq*.ios_IOSer.io_Length := 1;
checkDoIO(CMD_WRITE, "Write");
fi;
corp;
/*
* serialGetChar - upper level routine to get a character from the serial
* port. Echoing is done, as is line editing (backspace, CNTL-X).
*/
proc serialGetChar()char:
char ch;
if LineBuffPos = LineBuffMax then
LineBuffPos := 0;
LineBuffMax := 0;
while
ch := readSerial();
if ch = '\r' then
LineBuffer[LineBuffMax] := '\n';
LineBuffMax := LineBuffMax + 1;
writeSerial('\r');
writeSerial('\n');
false
elif ch = '\b' then
if LineBuffMax ~= 0 then
LineBuffMax := LineBuffMax - 1;
if EchoOn then
writeSerial('\b');
writeSerial(' ');
writeSerial('\b');
fi;
fi;
true
elif ch = '\(0x18)' then
while LineBuffMax ~= 0 do
LineBuffMax := LineBuffMax - 1;
if EchoOn then
writeSerial('\b');
writeSerial(' ');
writeSerial('\b');
fi;
od;
true
elif ch = '\(0x1c)' then
LineBuffer[LineBuffMax] := '\e';
LineBuffMax := LineBuffMax + 1;
false
elif ch >= ' ' and ch <= '~' then
if LineBuffMax < LINE_BUFFER_LENGTH - 1 then
LineBuffer[LineBuffMax] := ch;
LineBuffMax := LineBuffMax + 1;
if EchoOn then
writeSerial(ch);
fi;
fi;
true
else
true
fi
do
od;
fi;
LineBuffPos := LineBuffPos + 1;
LineBuffer[LineBuffPos - 1]
corp;
/*
* serialPutChar - upper level routine to write a character to the serial
* port. This one just turns '\n' into CR-LF.
*/
proc serialPutChar(char ch)void:
if ch = '\n' then
writeSerial('\r');
fi;
writeSerial(ch);
corp;
/*
* serialEcho - set/clear the echoing flag. (Used for passwords)
*/
proc serialEcho(bool enabled)void:
EchoOn := enabled;
corp;
/*
* serialActive - check for a connection. If there is one, set up the baud
* rate (2400, 1200, 300) and parity (none or even) and return 'true',
* else return 'false'.
*/
proc serialActive()bool:
bool callIncoming;
char ch;
LineSpeed := 2400;
setParams(false);
while
SerialDropped := false;
setParams(false);
checkDoIO(SDCMD_QUERY, "serialActive first query");
callIncoming := MySerReq*.ios_Status & CIAF_COMCD = 0;
if callIncoming then
ch := readSerial();
Delay(5);
checkDoIO(SDCMD_QUERY, "serialActive second query");
callIncoming := MySerReq*.ios_Status & CIAF_COMCD = 0;
fi;
callIncoming and ch ~= '\r' and ch ~= '\r' + 0x80
do
LineSpeed :=
if LineSpeed = 2400 then
1200
elif LineSpeed = 1200 then
300
else
2400
fi;
od;
if ch = '\r' + 0x80 and callIncoming then
setParams(true);
fi;
SerialDropped := not callIncoming;
callIncoming
corp;
/*
* serialSpeed - return a string giving the serial connection speed.
*/
proc serialSpeed()*char:
if LineSpeed = 2400 then
"2400"
elif LineSpeed = 1200 then
"1200"
else
"300"
fi
corp;
/*
* serialHungup - check to see if the user hung up.
*/
proc serialHungup()bool:
if SerialDropped then
true
else
checkDoIO(SDCMD_QUERY, "serialHungup");
if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
SerialDropped := true;
true
else
false
fi
fi
corp;
/*
* serialGotControlC - return 'true' if someone typed a control-C.
*/
proc serialGotControlC()bool:
char ch;
bool gotOne;
if SerialDropped then
true
else
gotOne := false;
while
checkDoIO(SDCMD_QUERY, "^C check");
if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
SerialDropped := true;
gotOne := true;
elif MySerReq*.ios_Status & (IOSTF_READBREAK << 8) ~= 0 then
gotOne := true;
fi;
not gotOne and MySerReq*.ios_IOSer.io_Actual ~= 0
do
MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
MySerReq*.ios_IOSer.io_Length := 1;
checkDoIO(CMD_READ, "^C read");
if ch = '\(0x03)' or ch = '\(0xff)' or ch = '\(0x7f)' then
gotOne := true;
fi;
od;
if gotOne then
checkDoIO(CMD_START, "^C start");
checkDoIO(CMD_CLEAR, "^C clear");
true
else
false
fi
fi
corp;